/** * Copyright (c) 2000-2017 Liferay, Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.liferay.faces.util.factory; import java.util.Iterator; import java.util.ServiceLoader; import javax.faces.FacesException; import javax.faces.context.ExternalContext; import com.liferay.faces.util.config.ConfiguredElement; /** * This class provides a factory lookup mechanism similar to the {@link javax.faces.FactoryFinder} in the JSF API. * Factory instances are stored as attributes in the {@link ExternalContext#getApplicationMap()}. * * @author Neil Griffin */ public abstract class FactoryExtensionFinder { // Private Static Data Members private static FactoryExtensionFinder instance; /** * @deprecated Call {@link #getFactory(ExternalContext, Class)} instead. * * <p>Returns the factory instance associated with the specified factory class from the external * context associated with the current faces context.</p> * * @param factoryClass The factory {@link java.lang.Class}. */ @Deprecated @SuppressWarnings("deprecation") public static Object getFactory(Class<?> factoryClass) { return getInstance().getFactoryInstance(factoryClass); } /** * Returns the factory instance associated with the specified factory class from the specified external context. * * @param externalContext The external context associated with the current faces context. * @param factoryClass The factory {@link java.lang.Class}. */ public static Object getFactory(ExternalContext externalContext, Class<?> factoryClass) { return getInstance().getFactoryInstance(externalContext, factoryClass); } /** * Returns the thread-safe Singleton instance of the factory extension finder. * * @throws FacesException When the factory extension finder cannot be discovered. */ public static FactoryExtensionFinder getInstance() throws FacesException { // This method of lazy-initialization is thread-safe because the FactoryExtensionFinder is first called during // ApplicationStartupListener.processSystemEvent(). ApplicationStartupListener.processSystemEvent() occurs // before multiple threads have the opportunity to concurrently access the FactoryExtensionFinder. if (instance == null) { ServiceLoader<FactoryExtensionFinder> serviceLoader = ServiceLoader.load(FactoryExtensionFinder.class); if (serviceLoader != null) { Iterator<FactoryExtensionFinder> iterator = serviceLoader.iterator(); while ((instance == null) && iterator.hasNext()) { instance = iterator.next(); } if (instance == null) { throw new FacesException("Unable locate service for " + FactoryExtensionFinder.class.getName()); } } else { throw new FacesException("Unable to acquire ServiceLoader for " + FactoryExtensionFinder.class.getName()); } } return instance; } /** * @deprecated Call {@link #getFactoryInstance(ExternalContext, Class)} instead. * * <p>Returns the factory instance associated with the specified factory class from the external * context associated with the current faces context.</p> * * @param factoryClass The factory {@link java.lang.Class}. */ @Deprecated public abstract Object getFactoryInstance(Class<?> factoryClass); /** * Returns the factory instance associated with the specified factory class from the specified external context. * * @param externalContext The external context associated with the current faces context. * @param factoryClass The factory {@link java.lang.Class}. */ public abstract Object getFactoryInstance(ExternalContext externalContext, Class<?> factoryClass); /** * @deprecated Call {@link #registerFactory(ExternalContext, ConfiguredElement)} instead. * * <p>Registers the specified configured factory extension by storing it as an attribute in the {@link * ExternalContext#getApplicationMap()} associated with the current faces context. Since this method is * designed to be called during application initialization, it is not guaranteed to be thread-safe.</p> * * @param configuredFactoryExtension The configured factory extension. */ @Deprecated public abstract void registerFactory(ConfiguredElement configuredFactoryExtension); /** * Registers the specified configured factory extension by storing it as an attribute in the specified {@link * ExternalContext#getApplicationMap()}. Since this method is designed to be called during application * initialization, it is not guaranteed to be thread-safe. * * @param externalContext The external context associated with the current faces context. * @param configuredFactoryExtension The configured factory extension. */ public abstract void registerFactory(ExternalContext externalContext, ConfiguredElement configuredFactoryExtension); /** * Releases all of the factories that were registered via the {@link #registerFactory(ExternalContext, * ConfiguredElement)} method. It is designed to be called when a webapp context is destroyed. */ public abstract void releaseFactories(ExternalContext externalContext); }